package com.lanyou.cook.web;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Tuple;
import javax.persistence.TypedQuery;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Path;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;

import org.apache.commons.beanutils.DynaBean;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import com.lanyou.cook.common.Constants;
import com.lanyou.cook.datadictionary.UserLogOpt;
import com.lanyou.cook.entity.domain.UserLog;
import com.lanyou.cook.repository.UserLogRepository;
import com.lanyou.cook.service.DataDictionaryService;
import com.lanyou.cook.util.DateUtil;
import com.lanyou.cook.web.param.UserLogParam;

/**
 * 用户日志相关业务控制层
 * 
 * @author 曾族根
 *
 */
@RestController
@RequestMapping(Constants.BASE_URL_API + "/userLogs")
public class UserLogController {
	@Autowired
	private DataDictionaryService dataDictionaryService;
	@PersistenceContext
	private EntityManager entityManager;
	@Autowired
	private UserLogRepository userLogRepository;

	/**
	 * 查询特定条件下的用户日志集合
	 * 
	 * @param param
	 *            类型:FieldParam 待查询的用户日志参数实体
	 * @param pageable
	 *            类型:Pageable 待查询的分页参数实体
	 * @return
	 */
	@RequestMapping("/search/findByExample")
	@RequiresPermissions(value={"systemUserLog:view"})
	public Page<UserLog> findByExample(UserLogParam param, Pageable pageable) {

		Specification<UserLog> spec = new Specification<UserLog>() {
			@Override
			public Predicate toPredicate(Root<UserLog> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
				List<Predicate> predicatesList = new ArrayList<>();

				if (StringUtils.isNotBlank(param.getOptPerson())) {
					predicatesList.add(cb.like(root.get("optPerson"), '%' + param.getOptPerson() + '%'));
				}
				if (StringUtils.isNoneBlank(param.getOptType())) {
					predicatesList.add(cb.equal(root.get("optType"), param.getOptType()));
				}

				if (param.getBeginOfCreateTime()==null) {
					param.setBeginOfCreateTime("1900-1-1 00:00:00");
				}
				
				DateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
				try {
					Date beginDate = sdf.parse(param.getBeginOfCreateTime());
					predicatesList.add(cb.greaterThan(root.get("optTime"), beginDate));
				} catch (ParseException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				
				if (param.getEndOfCreateTime()==null) {
					param.setEndOfCreateTime("2999-01-01 00:00:00");
				}
				
				try {
					Date endDate = sdf.parse(param.getEndOfCreateTime());
					predicatesList.add(cb.lessThan(root.get("optTime"), endDate));
				} catch (ParseException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}

				query.where(predicatesList.toArray(new Predicate[predicatesList.size()]));
				return null;

			}
		};

		return userLogRepository.findAll(spec, pageable);
	}

	// 统计查询功能
	/**
	 * 根据用户和操作日志类型统计次数
	 * 
	 * @param userCode
	 *            类型:String 用户账号
	 * @param optType
	 *            类型:String 操作类型
	 * @param optPerson
	 *            类型:String 操作人
	 * @param beginOfCreateTime
	 *            类型:Date 要查询的日志的开始时间
	 * @param endOfCreateTime
	 *            类型:Date 要查询的日志的结束时间
	 * @return 类型:String 用户操作日志信息
	 */
	@RequestMapping(value = "/statistics/forUserOPT", produces = "application/json")
	@RequiresPermissions(value={"systemUserOperationStatistics:view"})
	public String countByUserAndOpt( String optType, String optPerson,
			String beginOfCreateTime,
			String endOfCreateTime, Pageable pageable) {
		CriteriaBuilder cb = entityManager.getCriteriaBuilder();
		CriteriaQuery<Tuple> cq = cb.createTupleQuery();
		
		// 构建FROM
		Root<UserLog> rootUserLog = cq.from(UserLog.class);

		// 构建WHERE部分
		List<Predicate> predicatesList = new ArrayList<>();
		if (StringUtils.isNotBlank(optType)) {
			predicatesList.add(cb.equal(rootUserLog.get("optType"), optType));
		}
		if (StringUtils.isNotBlank(optPerson)) {
			predicatesList.add(cb.like(rootUserLog.get("optPerson"), '%' + optPerson + '%'));
		}
		
		if (beginOfCreateTime==null) {
			beginOfCreateTime="1900-1-1 00:00:00";
		}
		
		DateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		try {
			Date beginDate = sdf.parse(beginOfCreateTime);
			predicatesList.add(cb.greaterThan(rootUserLog.get("optTime"), beginDate));
		} catch (ParseException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		if (endOfCreateTime==null) {
			endOfCreateTime="2999-01-01 00:00:00";
		}
		
		try {
			Date endDate = sdf.parse(endOfCreateTime);
			predicatesList.add(cb.lessThan(rootUserLog.get("optTime"), endDate));
		} catch (ParseException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		

		cq.where(predicatesList.toArray(new Predicate[predicatesList.size()]));

		// 构建GROUP BY部分
		cq.groupBy(rootUserLog.get("optType"), rootUserLog.get("userCode"), rootUserLog.get("optPerson"));

		// 构建SELECT部分
		cq.multiselect(rootUserLog.get("optType").alias("optType"), rootUserLog.get("userCode").alias("userCode"),
				rootUserLog.get("optPerson").alias("optPerson"), cb.count(rootUserLog).alias("optAmount"));
		
		TypedQuery<Tuple> q = entityManager.createQuery(cq);
		
		// 分页
		q.setFirstResult(pageable.getOffset());
		q.setMaxResults(pageable.getPageSize());
		
		// 执行查询
		List<Tuple> queryResult = q.getResultList();

		JsonArray jsonDatas = new JsonArray();
		for (Tuple tuple : queryResult) {
			String oPTType = tuple.get("optType", String.class);
			oPTType = dataDictionaryService.getValueName(UserLogOpt.TypeCode, oPTType);
			String user = tuple.get("userCode", String.class);
			String person = tuple.get("optPerson", String.class);
			Long optAmount = tuple.get("optAmount", Long.class);

			JsonObject jo = new JsonObject();
			jo.addProperty("oPTType", oPTType);
			jo.addProperty("user", user);
			jo.addProperty("person", person);
			jo.addProperty("optAmount", optAmount);
			jsonDatas.add(jo);
		}

		JsonObject jsonResult = new JsonObject();
		jsonResult.add("content", jsonDatas);
		return jsonResult.toString();
	}

}